package com.jike.jkgame;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.widget.TabHost;

import com.jike.jkgame.data.Equipment;
import com.jike.jkgame.data.General;
import com.jike.jkgame.data.MiscDataHelper;
import com.jike.jkgame.data.Mission;
import com.jike.jkgame.data.Preferences;
import com.jike.jkgame.data.Skill;
import com.jike.jkgame.data.Treasure;
import com.jike.jkgame.data.UserStatus;
import com.jike.jkgame.exception.EncodingException;
import com.jike.jkgame.exception.NetworkErrorException;
import com.jike.jkgame.network.MessageFactory;
import com.jike.jkgame.network.NetworkUtilis;
import com.jike.jkgame.network.ServerConfig;
import com.jike.jkgame.widget.VerticalMarqueeTextView;
import com.jike.jkgame.widget.slidemenu.SlideBarMenu;
import com.jike.jkgame.widget.slidemenu.SlideBarMenu.MenuItemClickedListener;

public class MainActivity extends FragmentActivity {

	private static final int LOGIN = 1001;
	private static final int INIT_USER = 1002;

	TabHost mTabHost;
	TabManager mTabManager;
	VerticalMarqueeTextView mNotifyTv;
	private View mMainContainer;
	//private UserStatusFragment mStatusFragment;

	private Handler mHandler = new Handler(new Callback() {

		@Override
		public boolean handleMessage(Message msg) {
			String name = (String) msg.obj;
			if (name.equals("Energy")) {
				UserStatusViewManager.get().updateEnergyTimer(msg.arg1);
				if (msg.what == Global.MessageType.TIME_FINISH) {
					UserStatusViewManager.get().updateView(UserStatusFragment.ENERGY);
				}

			} else {
				UserStatusViewManager.get().updateVigourTimer(msg.arg1);
				if (msg.what == Global.MessageType.TIME_FINISH) {
					UserStatusViewManager.get().updateView(UserStatusFragment.VIGOUR);
				}
			}

			// if(msg.what == Global.MessageType.TIME_FINISH) {
			// mValueTv.setText(mStatus.value + "/" + mStatus.maxValue);
			// }

			return false;
		}
	});

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		checkLogin();

		setContentView(R.layout.main);
		mMainContainer = findViewById(R.id.main_container);

		mNotifyTv = (VerticalMarqueeTextView) findViewById(R.id.tv_notification);
		mNotifyTv
				.setText("This is a very very very very very very very very very very very very very very very very very long long long text!");

		mTabHost = (TabHost) findViewById(android.R.id.tabhost);
		mTabHost.setup();

		mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent);

		mTabManager.addTab(mTabHost.newTabSpec("home").setIndicator("Home"),
				HomeFragment.class, null);
		mTabManager.addTab(mTabHost.newTabSpec("friends").setIndicator("Friends"),
				FriendsFragment.class, null);
		mTabManager.addTab(
				mTabHost.newTabSpec("treasure").setIndicator("Treasure"),
				TreasureFragment.class, null);
		mTabManager.addTab(
				mTabHost.newTabSpec("strengthen").setIndicator("Strengthen"),
				StrengthenFragment.class, null);
		mTabManager.addTab(
				mTabHost.newTabSpec("attack").setIndicator("Attack"),
				AttackFragment.class, null);
		mTabManager.addTab(mTabHost.newTabSpec("lineup")
				.setIndicator("Line-up"), LineupFragment.class, null);
		mTabManager.addTab(
				mTabHost.newTabSpec("mission").setIndicator("Mission"),
				MissionFragment.class, null);

		if (savedInstanceState != null) {
			mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
		}

		SlideBarMenu menu = (SlideBarMenu) findViewById(R.id.menu);

		// List<SlideMenuItem> items = new ArrayList<SlideMenuItem>();
		// items.add(new SlideMenuItem(0, R.drawable.ic_menu_home));
		// items.add(new SlideMenuItem(1, R.drawable.ic_menu_mission));
		// items.add(new SlideMenuItem(2, R.drawable.ic_menu_attack));
		// items.add(new SlideMenuItem(3, R.drawable.ic_menu_lineup));
		// items.add(new SlideMenuItem(4, R.drawable.ic_menu_strengthen));
		// items.add(new SlideMenuItem(5, R.drawable.ic_menu_treasure));
		// menu.addItems(items);

		menu.setOnItemClickedListener(new MenuItemClickedListener() {

			public void eventOccured(int id) {
				mTabHost.setCurrentTab(id);

				switch (id) {
				case 6: // mission
					mMainContainer.setBackgroundResource(R.drawable.mission_bg);
					break;

				default: // home and others
					mMainContainer.setBackgroundResource(R.drawable.home_bg);
					break;
				}
				
			}
		});

		ParseResouceFilesTask task = new ParseResouceFilesTask();
		task.execute(null);

	}

	private void getUserInfo() {
		GetUserInfoTask task = new GetUserInfoTask();
		task.execute(null);
	}

	public void updateUserStatus(int flag) {
		UserStatusViewManager.get().updateView(flag);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString("tab", mTabHost.getCurrentTabTag());
	}

	public static class TabManager implements TabHost.OnTabChangeListener {
		private final FragmentActivity mActivity;
		private final TabHost mTabHost;
		private final int mContainerId;
		private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
		TabInfo mLastTab;

		static final class TabInfo {
			private final String tag;
			private final Class<?> clss;
			private final Bundle args;
			private Fragment fragment;

			TabInfo(String _tag, Class<?> _class, Bundle _args) {
				tag = _tag;
				clss = _class;
				args = _args;
			}
		}

		static class DummyTabFactory implements TabHost.TabContentFactory {
			private final Context mContext;

			public DummyTabFactory(Context context) {
				mContext = context;
			}

			@Override
			public View createTabContent(String tag) {
				View v = new View(mContext);
				v.setMinimumWidth(0);
				v.setMinimumHeight(0);
				return v;
			}
		}

		public TabManager(FragmentActivity activity, TabHost tabHost,
				int containerId) {
			mActivity = activity;
			mTabHost = tabHost;
			mContainerId = containerId;
			mTabHost.setOnTabChangedListener(this);
		}

		public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
			tabSpec.setContent(new DummyTabFactory(mActivity));
			String tag = tabSpec.getTag();

			TabInfo info = new TabInfo(tag, clss, args);

			// Check to see if we already have a fragment for this tab, probably
			// from a previously saved state. If so, deactivate it, because our
			// initial state is that a tab isn't shown.
			info.fragment = mActivity.getSupportFragmentManager()
					.findFragmentByTag(tag);
			if (info.fragment != null && !info.fragment.isDetached()) {
				FragmentTransaction ft = mActivity.getSupportFragmentManager()
						.beginTransaction();
				ft.detach(info.fragment);
				ft.commit();
			}

			mTabs.put(tag, info);
			mTabHost.addTab(tabSpec);
		}

		@Override
		public void onTabChanged(String tabId) {
			TabInfo newTab = mTabs.get(tabId);
			if (mLastTab != newTab) {
				FragmentTransaction ft = mActivity.getSupportFragmentManager()
						.beginTransaction();
				if (mLastTab != null) {
					if (mLastTab.fragment != null) {
						ft.detach(mLastTab.fragment);
					}
				}
				if (newTab != null) {
					if (newTab.fragment == null) {
						newTab.fragment = Fragment.instantiate(mActivity,
								newTab.clss.getName(), newTab.args);
						ft.add(mContainerId, newTab.fragment, newTab.tag);
					} else {
						ft.attach(newTab.fragment);
					}
				}

				mLastTab = newTab;
				ft.commit();
				mActivity.getSupportFragmentManager()
						.executePendingTransactions();
			}
		}
	}

	@Override
	protected void onStop() {
		// UserStatusDAO userDao = new UserStatusDAO(getApplicationContext());
		// userDao.open();
		// userDao.saveStatus(UserStatus.get());
		// userDao.close();
		super.onStop();
	}

	@Override
	protected void onResume() {
		super.onResume();
		UserStatus.get().getEnergy().setTargetHandler(mHandler);
		UserStatus.get().getVigour().setTargetHandler(mHandler);
	}

	private boolean checkLogin() {
		if (UserStatus.get().isLogedin()) {
			getUserInfo();
			return true;
		} else {
			LoginTask task = new LoginTask();
			task.execute(null);
			return false;
		}

	}

	private void gotoLoginActivity() {
		Intent intent = new Intent(MainActivity.this, LoginActivity.class);
		startActivityForResult(intent, LOGIN);
	}

	class LoginTask extends AsyncTask<Object, Integer, Integer> {

		@Override
		protected Integer doInBackground(Object... params) {
			Log.d("test", "Login task");

			Preferences pref = Preferences.get();
			String name = pref.getString(Preferences.Keys.UserName);
			String password = pref.getString(Preferences.Keys.Password);

			if (name == null || password == null) {
				return -1;
			}

			JSONObject req = MessageFactory.createLoginMessage(name, password);

			try {
				String response = NetworkUtilis.getHttpString(
						ServerConfig.getStaticLoginServer(), req);
				if (response == null) {
					return -1;
				}

				JSONObject json = new JSONObject(response);

				int opcode = json.optInt("oc", -1);

				if (opcode != 0) {
					return opcode;
				}

				UserStatus.get().setUid(json.optLong("id"));
				return 0;

			} catch (NetworkErrorException e) {
				e.printStackTrace();
			} catch (EncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}

			return -1;
		}

		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
			if (result == null || result != 0) {
				gotoLoginActivity();
			} else {
				getUserInfo();
			}
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

	}

	class GetUserInfoTask extends AsyncTask<Object, Integer, Integer> {

		@Override
		protected Integer doInBackground(Object... params) {
			JSONObject req = MessageFactory.createGetUserInfoReqMessage();

			try {
				String response = NetworkUtilis.getHttpString(ServerConfig
						.get().getGameServer(), req);
				if (response == null) {
					return null;
				}

				JSONObject json = new JSONObject(response);

				int opcode = json.optInt("opcode");
				if (opcode != 0) {
					return opcode;
				}

				UserStatus user = UserStatus.get();
				user.setName(json.optString("rname"));
				user.setLevel(json.optInt("level"));
				user.setExpierence(json.optInt("exp"));
				user.setEnergy(json.optInt("energy"));
				user.setVigour(json.optInt("virgour"));
				user.setMoney(json.optInt("money"));
				user.setCash(json.optInt("cash"));
				long cur_time = json.optLong("cur_time");
				long energy_ts = json.optLong("energy_ts");
				long vigour_ts = json.optLong("vigour_ts");
				user.getEnergy().passTime(cur_time - energy_ts);
				user.getVigour().passTime(cur_time - vigour_ts);

				return 0;
			} catch (NetworkErrorException e) {
				e.printStackTrace();
			} catch (EncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Integer result) {
			if (result == null) {
				// TODO 处理错误
				return;
			}
			if (result == 0) {
				UserStatusViewManager.get().updateView(UserStatusFragment.FLAG_ALL);
			} else if (result == 304) {
				// 用户未初始化
				Intent intent = new Intent(MainActivity.this,
						UserInitActivity.class);
				startActivityForResult(intent, INIT_USER);
			}
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

	}

	@Override
	protected void onActivityResult(int requesCode, int resultCode, Intent data) {
		super.onActivityResult(requesCode, resultCode, data);
		if (requesCode == LOGIN || requesCode == INIT_USER) {
			if (resultCode == 1) {
				getUserInfo();
			}
		}
	}

	class ParseResouceFilesTask extends AsyncTask<Object, Integer, Integer> {

		@Override
		protected Integer doInBackground(Object... params) {

			int count = 0;

			// 处理任务数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/mission.dat");
				boolean ok = Mission.parsDataFile(in);

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 武将数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/general.dat");
				count = General.parseDataFile(in);

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 装备数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/equipment.dat");
				count = Equipment.parseDataFile(in);
				// missionFile.delete();

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 技能数据
			try {
				InputStream in = JKApp.get().getAssets().open("res/skill.dat");
				count = Skill.parseDataFile(in);

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 碎片数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/fragment.dat");
				count = com.jike.jkgame.data.Fragment.parseDataFile(in);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// 宝物数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/treasure.dat");
				count = Treasure.parseDataFile(in);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			// 基础数据
			try {
				InputStream in = JKApp.get().getAssets()
						.open("res/misc.dat");
				count = MiscDataHelper.parseDataFile(in);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return count;
		}

	}

}
